package com.cqgc.AliPay;

import cn.hutool.core.date.DateTime;
import cn.hutool.json.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;

import com.cqgc.mapper.OrderMapper;
import com.cqgc.pojo.entity.Order;
import com.cqgc.pojo.entity.Result;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

// bngjag1420@sandbox.com
// 111111
@RestController
@RequestMapping("/alipay")
public class AliPayController {
    private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
    private static final String FORMAT = "JSON";
    private static final String CHARSET = "UTF-8";
    //签名方式
    private static final String SIGN_TYPE = "RSA2";

    @Resource
    private AlipayConfig aliPayConfig;

    @Resource
    private OrderMapper ordersMapper;

    /**
     * 处理支付请求的接口方法。
     * 使用支付宝的页面支付接口，将支付表单直接返回给客户端。
     *
     * @param aliPay 包含支付相关信息的对象，如订单编号、总金额、支付名称等。
     * @param httpResponse 用于向客户端响应支付表单的HttpServletResponse对象。
     * @throws Exception 如果处理过程中发生错误，则抛出异常。
     */
    @GetMapping("/pay") // &subject=xxx&traceNo=xxx&totalAmount=xxx
    public void pay(AliPay aliPay, HttpServletResponse httpResponse) throws Exception {
        // 创建支付宝客户端，用于调用支付宝API
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);

        // 配置支付请求参数
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setNotifyUrl(aliPayConfig.getNotifyUrl()); // 设置异步通知地址
        request.setReturnUrl(aliPayConfig.getReturnUrl()); // 设置同步跳转地址
        JSONObject bizContent = new JSONObject();
        bizContent.set("out_trade_no", aliPay.getTraceNo()); // 设置订单编号
        bizContent.set("total_amount", aliPay.getTotalAmount()); // 设置订单总金额
        bizContent.set("subject", aliPay.getSubject()); // 设置支付名称
        bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY"); // 设置产品代码
        request.setBizContent(bizContent.toString());

        // 执行支付请求，获取表单HTML内容
        String form = "";
        try {
            form = alipayClient.pageExecute(request).getBody(); // 调用支付宝SDK生成支付表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        // 将支付表单直接写入HTTP响应，供客户端展示
        httpResponse.setContentType("text/html;charset=" + CHARSET);
        httpResponse.getWriter().write(form); // 输出支付表单HTML
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }

    /**
     * 处理支付宝异步通知的请求。
     *
     * @param request HttpServletRequest对象，用于接收支付宝异步通知的参数。
     * @return 返回字符串"success"，表示通知处理成功。
     * @throws Exception 抛出异常，处理请求过程中遇到的错误。
     */
    @PostMapping("/notify")
    public String payNotify(HttpServletRequest request) throws Exception {
        // 检查交易状态是否为成功
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
            System.out.println("=========支付宝异步回调========");

            // 收集请求中的所有参数
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                params.put(name, request.getParameter(name));
            }

            // 提取订单号和交易号等关键信息
            String outTradeNo = params.get("out_trade_no");
            System.out.println("商户订单号 = " + outTradeNo);
            String gmtPayment = params.get("gmt_payment");
            String alipayTradeNo = params.get("trade_no");
            System.out.println("支付宝交易号 = " + alipayTradeNo);

            // 验证签名
            String sign = params.get("sign");
            String content = AlipaySignature.getSignCheckContentV1(params);
            boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, aliPayConfig.getAlipayPublicKey(), "UTF-8");
            if (checkSignature) {
                // 验签通过，处理业务逻辑
                System.out.println("交易名称: " + params.get("subject"));
                System.out.println("交易状态: " + params.get("trade_status"));
                System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
                System.out.println("商户订单号: " + params.get("out_trade_no"));
                System.out.println("交易金额: " + params.get("total_amount"));
                System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
                System.out.println("买家付款时间: " + params.get("gmt_payment"));
                System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));

                // 根据商户订单号查询订单
                Order order = ordersMapper.findById(outTradeNo);
                System.out.println(order);

                if (order != null) {
                    // 更新订单状态为支付成功
                    order.setAlipayNo(alipayTradeNo);
                    order.setStatus(0);
                    order.setOid(order.getOid());
                    order.setUpdateTime(LocalDateTime.now());
                    ordersMapper.updateOrder(order);
                }
            }
        }
        return "success";
    }

}


